package com.xjrsoft.module.app.utils;

import com.xjrsoft.core.tool.node.ForestNodeMerger;
import com.xjrsoft.core.tool.utils.BeanUtil;
import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.StringPool;
import com.xjrsoft.core.tool.utils.StringUtil;
import com.xjrsoft.module.app.entity.XjrAppFunctionButton;
import com.xjrsoft.module.app.entity.XjrAppFunctionColumn;
import com.xjrsoft.module.app.entity.XjrAppFunctionForm;
import com.xjrsoft.module.app.vo.AppFunctionCategoryTree;
import com.xjrsoft.module.app.vo.AppFunctionTreeVo;
import com.xjrsoft.module.app.vo.IFunctionVo;
import com.xjrsoft.module.base.vo.DataItemDetailVo;
import com.xjrsoft.module.form.constant.FormConstants;
import com.xjrsoft.module.form.util.FormDataUtil;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public final class FunctionUtil {

    public static final String[] ENABLED_BUTTONS = {"add", "modify", "delete", "view"};

    private FunctionUtil(){}

    public static List<XjrAppFunctionButton> buildButtonEntities(String functionId, String prefixEnCode, List<Map<String, Object>> buttonList) {
        List<XjrAppFunctionButton> resultList = new ArrayList<>();
        for (Map<String, Object> buttonMap : buttonList) {
            String encode = MapUtils.getString(buttonMap, "val");
            if (!ArrayUtils.contains(ENABLED_BUTTONS, encode)) {
                continue;
            }
            XjrAppFunctionButton button = new XjrAppFunctionButton();
            button.setEnCode(prefixEnCode + StringPool.COLON + encode);
            button.setFullName(MapUtils.getString(buttonMap, "name"));
            button.setFunctionId(functionId);
            resultList.add(button);
        }
        return resultList;
    }

    public static List<XjrAppFunctionColumn> buildColumnEntities(String functionId, List<Map<String, Object>> columnList) {
        List<XjrAppFunctionColumn> resultList = new ArrayList<>();
        for (Map<String, Object> columnMap : columnList) {
            XjrAppFunctionColumn column = new XjrAppFunctionColumn();
            column.setEnCode(MapUtils.getString(columnMap, "bindColumn"));
            column.setFullName(MapUtils.getString(columnMap, "fieldName"));
            column.setFunctionId(functionId);
            resultList.add(column);
        }
        return resultList;
    }

    public static List<XjrAppFunctionForm> buildFormEntities(String functionId, List<Map<String, Object>> formList) {
        List<Map<String, Object>> fullFieldList = FormDataUtil.getFullFieldList(formList);
        List<XjrAppFunctionForm> resultList = new ArrayList<>();
        for (Map<String, Object> formMap : fullFieldList) {
            Map<String, Object> config = MapUtils.getMap(formMap, FormConstants.CONFIG);
            String fieldName = MapUtils.getString(config, "bindTableField");
            if (StringUtils.isEmpty(fieldName)) {
                continue;
            }
            XjrAppFunctionForm form = new XjrAppFunctionForm();
            String id = MapUtils.getString(config, "appFormId");
            if (!StringUtils.isEmpty(id)) {
                form.setId(id);
            }
            form.setEnCode(fieldName);
            form.setFullName(MapUtils.getString(config, "label"));
            form.setFunctionId(functionId);
            form.setParentId(MapUtils.getString(config, "parentId"));
            resultList.add(form);
        }
        return resultList;
    }

    public static <T extends IFunctionVo> List<AppFunctionTreeVo> buildSubFunctionTree(List<AppFunctionTreeVo> functionTreeVoList,
                                                                                 List<?> subFunctionList,
                                                                                 Class<T> subFunctionClass) {
        List<AppFunctionTreeVo> subModuleVoList = BeanUtil.deepCopy(functionTreeVoList);
        List<T> subVoList = ForestNodeMerger.merge(BeanUtil.copyList(subFunctionList, subFunctionClass));
        for (T subEntity : subVoList) {
            for (AppFunctionTreeVo functionTreeVo : subModuleVoList) {
                if (StringUtil.equalsIgnoreCase(subEntity.getFunctionId(), functionTreeVo.getId())) {
                    functionTreeVo.getChildren().add(subEntity);
                }
            }
        }
        List<AppFunctionTreeVo> resultList = subModuleVoList.stream().filter(function -> CollectionUtil.isNotEmpty(function.getChildren())).collect(Collectors.toList());
        return resultList;
    }

    public static List<Object> buildCategoryTree(List<DataItemDetailVo> dataItemDetailVoList, List<AppFunctionTreeVo> appFunctionVoList) {
        List<DataItemDetailVo> itemDetailVoList = BeanUtil.deepCopy(dataItemDetailVoList);
        List<Object> resultList = new ArrayList<>();
        for (DataItemDetailVo itemDetailVo : itemDetailVoList) {
            AppFunctionCategoryTree tree = new AppFunctionCategoryTree();
            tree.setId(itemDetailVo.getItemDetailId());
            tree.setName(itemDetailVo.getItemName());
            tree.setType(itemDetailVo.getItemValue());
            List<AppFunctionTreeVo> subList = new ArrayList<>();
            for (AppFunctionTreeVo appFunctionVo : appFunctionVoList) {
                if (StringUtil.equals(appFunctionVo.getType(), itemDetailVo.getItemValue())) {
                    subList.add(appFunctionVo);
                    appFunctionVo.setParentId(itemDetailVo.getItemDetailId());
                }
            }
            tree.setChildren(subList);
            resultList.add(tree);
        }
        for (AppFunctionTreeVo appFunctionVo : appFunctionVoList) {
            if (org.apache.commons.lang3.StringUtils.isEmpty(appFunctionVo.getType())) {
                resultList.add(appFunctionVo);
            }
        }
        return resultList;
    }
}
